"""
商品评分分析器
用于计算商品的各维度得分并确定最终等级
"""
from typing import Dict, List, Tuple, Optional
from datetime import datetime, timedelta
import numpy as np
from scipy import stats
from dataclasses import dataclass
import json
from com.db.scan_record_manager import ScanRecordManager
from com.db.scan_record_price_analysis_manager import ScanRecordPriceAnalysisManager
from com.db.goods_score_manager import GoodsScoreManager
from com.utils.logger import get_logger
import threading
import time

logger = get_logger("GoodsScoreAnalyzer")

@dataclass
class ScoreResult:
    """评分结果数据类"""
    goods_id: int
    
    # 主要评分
    price_stability_score: float = 0    # 价格稳定性得分
    profit_potential_score: float = 0   # 利润空间得分
    trading_frequency_score: float = 0  # 交易频率得分
    price_trend_score: float = 0        # 价格趋势得分
    time_activity_score: float = 0      # 时间活跃度得分
    historical_success_score: float = 0  # 历史成功率得分
    total_score: float = 0              # 总分
    grade: str = 'C'                    # 等级

    # 价格稳定性子评分
    stability_cv_score: float = 0  # 稳定性-变异系数评分
    stability_volatility_score: float = 0  # 稳定性-波动率评分

    # 利润空间子评分
    profit_rate_score: float = 0  # 利润-利润率评分
    profit_frequency_score: float = 0  # 利润-频率评分
    profit_time_weighted_score: float = 0  # 利润-时间衰减评分

    # 交易频率子评分
    frequency_activity_score: float = 0  # 频率-活动频率评分
    frequency_selling_change_score: float = 0  # 频率-在售数量变化得分
    frequency_price_fluctuation_score: float = 0  # 频率-价格波动得分
    
    # 价格趋势子评分
    trend_direction_score: float = 0  # 趋势-方向和强度得分
    trend_range_score: float = 0  # 趋势-价格变化幅度得分
    trend_stability_score: float = 0  # 趋势-稳定性得分

    # 附加信息
    last_7d_trade_count: int = 0        # 最近7天交易次数
    last_7d_avg_price: float = 0        # 最近7天平均价格
    price_variance: float = 0           # 价格离散度
    success_rate: float = 0             # 成功率

class GoodsScoreAnalyzer:
    """商品评分分析器"""
    
    def __init__(self, interval_hours: int = 1):
        """初始化分析器
        
        Args:
            interval_hours: 定时分析间隔小时数，默认1小时
        """
        self.interval_hours = interval_hours
        self.running = False
        self.thread = None
        self.scan_record_manager = ScanRecordManager()
        self.price_analysis_manager = ScanRecordPriceAnalysisManager()
        self.score_manager = GoodsScoreManager()
        
    def start(self):
        """启动定时分析"""
        if self.running:
            logger.warning("商品评分定时分析已经在运行中")
            return
            
        self.running = True
        self.thread = threading.Thread(target=self._run, daemon=True)
        self.thread.start()
        logger.info(f"商品评分定时分析已启动，间隔{self.interval_hours}小时")
        
    def stop(self):
        """停止定时分析"""
        self.running = False
        if self.thread:
            self.thread.join()
            self.thread = None
        logger.info("商品评分定时分析已停止")
        
    def _run(self):
        """运行定时分析任务"""
        while self.running:
            try:
                # 等待到下一次分析时间
                logger.info(f"下次商品评分分析将在 {self.interval_hours} 小时后进行")
                time.sleep(self.interval_hours * 3600)
                
                # 如果仍在运行，则执行分析
                if self.running:
                    # 执行一次完整的分析
                    logger.info("开始执行商品评分分析...")
                    self.analyze_all()
                    logger.info("商品评分分析完成")
                    
            except Exception as e:
                logger.error(f"商品评分定时分析出错: {str(e)}")
                if self.running:
                    time.sleep(300)  # 发生错误时等待5分钟后重试

    def calculate_price_stability_score(self, goods_id: int, history_prices: List[float]) -> Tuple[float, float, float]:
        """
        计算价格稳定性得分（10分）
        返回：(总分, 变异系数评分, 波动率评分)
        """
        if not history_prices:
            return (0, 0, 0)
            
        # 计算价格统计指标
        avg_price = np.mean(history_prices)
        std_price = np.std(history_prices)
        price_range = max(history_prices) - min(history_prices)
        
        # 计算变异系数和波动率
        cv = std_price / avg_price if avg_price > 0 else float('inf')
        volatility = price_range / avg_price if avg_price > 0 else float('inf')
        
        # 评分规则
        cv_score = 0
        volatility_score = 0
        
        # 变异系数评分（5分）
        if cv < 0.05:
            cv_score = 5
        elif cv < 0.1:
            cv_score = 3.75
        elif cv < 0.15:
            cv_score = 2.5
        elif cv < 0.2:
            cv_score = 1.25
            
        # 波动率评分（5分）
        if volatility < 0.1:
            volatility_score = 5
        elif volatility < 0.2:
            volatility_score = 3.75
        elif volatility < 0.3:
            volatility_score = 2.5
        elif volatility < 0.4:
            volatility_score = 1.25
            
        total_score = cv_score + volatility_score
        return (total_score, cv_score, volatility_score)

    def calculate_profit_potential_score(self, goods_id: int) -> Tuple[float, float, float, float]:
        """
        计算利润空间得分（40分）
        结合异常价格统计和时间衰减因子
        返回：(总分, 利润率评分, 频率评分, 时间衰减评分)
        """
        try:
            # 获取最新的价格分析数据
            analysis = self.price_analysis_manager.get_latest_analysis(goods_id)
            if not analysis:
                return (0, 0, 0, 0)
                
            common_sell_price = analysis.get('common_sell_price', 0)
            if common_sell_price <= 0:
                return (0, 0, 0, 0)
                
            # 获取异常价格统计数据
            abnormal_prices = analysis.get('abnormal_prices', [])
            if not abnormal_prices:
                return (0, 0, 0, 0)
                
            # 获取最近7天的分析历史
            history_data = self.price_analysis_manager.get_analysis_history(goods_id, days=7)
            if not history_data:
                return (0, 0, 0, 0)
                
            # 1. 计算基于利润率的得分
            profit_rate_score = 0
            for price_data in abnormal_prices:
                if not isinstance(price_data, dict):
                    continue
                    
                price = price_data.get('price', 0)
                count = price_data.get('count', 0)
                profit_rate = price_data.get('profit_rate', 0)
                
                if price <= 0 or count <= 0 or profit_rate <= 0:
                    continue
                    
                # 利润率权重 - 提高权重值
                if profit_rate >= 20:
                    weight = 15  # 提高到15
                elif profit_rate >= 6:
                    weight = 6   # 提高到9
                elif profit_rate >= 5:
                    weight = 4   # 提高到6
                else:
                    continue
                    
                # 考虑出现次数，但用开平方避免次数过多导致分数过高
                profit_rate_score += weight * (count ** 0.5)
                
            # 将profit_rate_score标准化到0-20分
            profit_rate_score = min(profit_rate_score / 10, 20)
            
            # 2. 计算基于出现频率的得分
            frequency_score = 0
            total_abnormal_count = sum(price_data.get('count', 0) for price_data in abnormal_prices if isinstance(price_data, dict))
            
            # 计算实际的统计天数
            dates = []
            for record in history_data:
                record_time = record['analysis_time']
                if isinstance(record_time, str):
                    record_time = datetime.fromisoformat(record_time.replace('Z', '+00:00'))
                dates.append(record_time.date())
            
            # 计算实际的天数跨度
            if dates:
                min_date = min(dates)
                max_date = max(dates)
                date_span = (max_date - min_date).days + 1  # +1是因为包含首尾两天
                date_span = max(1, date_span)  # 确保至少为1天
            else:
                date_span = 1
            
            # 计算平均每天的异常价格出现次数
            daily_abnormal_count = total_abnormal_count / date_span
            
            logger.info(f"异常价格频率统计 - 总次数: {total_abnormal_count}, 统计天数: {date_span}, "
                       f"日均次数: {daily_abnormal_count:.2f}")
            
            # 频率评分规则（10分）
            if daily_abnormal_count >= 15:
                frequency_score = 10
            elif daily_abnormal_count >= 5:
                frequency_score = 5
            elif daily_abnormal_count >= 1:
                frequency_score = 2
                
            logger.info(f"频率得分: {frequency_score}分 (日均异常价格次数: {daily_abnormal_count:.2f})")
            
            # 3. 应用时间衰减因子（10分）
            now = datetime.now()
            time_weighted_score = 0
            total_weight = 0
            
            for record in history_data:
                # 获取该记录的异常价格
                record_abnormal_prices = record.get('abnormal_prices', [])
                if not record_abnormal_prices:
                    continue
                    
                # 计算时间权重（越近权重越大）
                record_time = record['analysis_time']
                if isinstance(record_time, str):
                    record_time = datetime.fromisoformat(record_time.replace('Z', '+00:00'))
                    
                days_diff = (now - record_time).days
                time_weight = 1.0 / (1 + days_diff)  # 时间衰减函数
                
                # 计算该记录的得分
                record_score = sum(
                    price_data.get('profit_rate', 0) * price_data.get('count', 0)
                    for price_data in record_abnormal_prices
                    if isinstance(price_data, dict)
                )
                
                time_weighted_score += record_score * time_weight
                total_weight += time_weight
            
            # 归一化时间加权得分到0-10分
            if total_weight > 0:
                time_weighted_score = min(time_weighted_score / (total_weight * 100), 10)
            else:
                time_weighted_score = 0
            
            # 计算总分
            total_score = profit_rate_score + frequency_score + time_weighted_score
            
            return (total_score, profit_rate_score, frequency_score, time_weighted_score)
            
        except Exception as e:
            logger.error(f"计算商品 {goods_id} 的利润空间得分时出错: {str(e)}", exc_info=True)
            return (0, 0, 0, 0)

    def calculate_trading_frequency_score(self, goods_id: int) -> Tuple[float, float, float, float]:
        """
        计算交易频率得分（40分）
        包含三个维度：
        1. 活动频率（30分）- 根据扫描记录的频率评分
        2. 在售数量变化（7分）- 根据在售数量的减少情况评分
        3. 价格波动（3分）- 根据最低价格区间的变化评分
        """
        try:
            now = datetime.now()
            week_ago = now - timedelta(days=7)
            
            # 获取最近7天的扫描记录
            records = self.scan_record_manager.get_records_by_goods_id(goods_id, start_time=week_ago)
            if not records:
                logger.warning(f"商品 {goods_id} 没有扫描记录")
                return (0, 0, 0, 0)
            
            # 1. 活动频率得分（30分）
            daily_activities = {}
            min_date = None
            max_date = None
            
            # 记录每天的活动次数
            for record in records:
                day = record['create_at'].date()
                daily_activities[day] = daily_activities.get(day, 0) + 1
                if min_date is None or day < min_date:
                    min_date = day
                if max_date is None or day > max_date:
                    max_date = day
            
            # 计算实际的天数跨度
            if min_date and max_date:
                date_span = (max_date - min_date).days + 1  # +1是因为包含首尾两天
                date_span = max(1, date_span)  # 确保至少为1天
            else:
                date_span = 1
            
            # 获取每天的活动次数列表
            daily_counts = list(daily_activities.values())
            if not daily_counts:
                return (0, 0, 0, 0)
                
            # 计算活动次数的统计指标
            max_daily = max(daily_counts)
            avg_daily = sum(daily_counts) / len(daily_counts)
            
            # 计算平均每日活动次数
            avg_daily_activities = len(records) / date_span
            
            # 计算活跃度比例
            activity_ratio = avg_daily_activities / max_daily if max_daily > 0 else 0
            
            # 根据比例评分（30分）
            if activity_ratio >= 0.9:      # 达到最高活动次数的90%以上
                activity_score = 30
            elif activity_ratio >= 0.7:    # 达到最高活动次数的70%以上
                activity_score = 22
            elif activity_ratio >= 0.5:    # 达到最高活动次数的50%以上
                activity_score = 15
            elif activity_ratio >= 0.3:    # 达到最高活动次数的30%以上
                activity_score = 8
            else:                          # 低于30%
                activity_score = 3
            
            logger.info(f"活动频率得分：数据跨度{date_span}天，单日最高{max_daily}次，日均{avg_daily:.1f}次，"
                       f"平均每日活动{avg_daily_activities:.1f}次，活跃度比例{activity_ratio:.2%}，得分{activity_score}分")
            
            # 2. 在售数量变化得分（7分）
            sorted_records = sorted(records, key=lambda x: x['create_at'])
            daily_sales = {}
            max_daily_decrease = 0  # 记录最大单日减少量
            prev_record = None
            
            for record in sorted_records:
                day = record['create_at'].date()
                curr_count = record.get('selling_count')
                
                if curr_count is None:  # 跳过没有在售数量的记录
                    continue
                    
                if prev_record:
                    prev_count = prev_record.get('selling_count')
                    if prev_count is not None and curr_count is not None and prev_count > curr_count:
                        change = prev_count - curr_count
                        daily_sales[day] = change
                        max_daily_decrease = max(max_daily_decrease, change)
                        
                prev_record = record
            
            # 计算每天的销量变化比例（相对于最大减少量）
            total_sales = sum(daily_sales.values())
            avg_daily_sales = total_sales / date_span if daily_sales else 0
            sales_ratio = avg_daily_sales / max_daily_decrease if max_daily_decrease > 0 else 0
            
            # 根据比例评分（7分）
            if sales_ratio >= 0.8:      # 平均销量达到最大减少量的80%以上
                sales_score = 7
            elif sales_ratio >= 0.6:    # 达到60%以上
                sales_score = 5
            elif sales_ratio >= 0.4:    # 达到40%以上
                sales_score = 3
            elif sales_ratio >= 0.2:    # 达到20%以上
                sales_score = 2
            elif sales_ratio > 0:       # 有销量变化
                sales_score = 1
            else:
                sales_score = 0
            
            logger.info(f"在售数量变化得分：数据跨度{date_span}天，最大单日减少{max_daily_decrease}个，总减少{total_sales}个，"
                       f"日均减少{avg_daily_sales:.1f}个，变化比例{sales_ratio:.2%}，得分{sales_score}分")
            
            # 3. 价格波动得分（3分）
            price_changes = []
            max_price_change = 0  # 记录最大价格变化幅度
            prev_lowest_prices = None
            price_change_days = set()  # 记录发生价格变化的天数
            
            for record in sorted_records:
                try:
                    price_list_str = record.get('price_list')
                    if not price_list_str:
                        continue
                        
                    price_list = json.loads(price_list_str)
                    if not price_list:
                        continue
                    
                    # 确保价格列表中的值都是数字
                    price_list = [float(p) for p in price_list if p is not None]
                    if not price_list:
                        continue
                    
                    day = record['create_at'].date()
                    has_change = False
                    
                    # 计算最低3个价格的平均值
                    lowest_avg = sum(price_list[:3]) / min(3, len(price_list))
                    
                    # 检查最低价格区间的差异
                    if len(price_list) >= 3:
                        if price_list[0] > 0:  # 避免除以零
                            price_gap_rate = (price_list[2] - price_list[0]) / price_list[0]
                            if price_gap_rate > 0.05:  # 最低3个价格差异超过5%
                                price_changes.append(price_gap_rate)
                                max_price_change = max(max_price_change, price_gap_rate)
                                has_change = True
                    
                    # 检查最低价的变化
                    if prev_lowest_prices:
                        prev_lowest_avg = sum(prev_lowest_prices[:3]) / min(3, len(prev_lowest_prices))
                        if prev_lowest_avg > 0:  # 避免除以零
                            change_rate = abs(lowest_avg - prev_lowest_avg) / prev_lowest_avg
                            if change_rate > 0.05:  # 最低价区间变化超过5%
                                price_changes.append(change_rate)
                                max_price_change = max(max_price_change, change_rate)
                                has_change = True
                    
                    if has_change:
                        price_change_days.add(day)
                    
                    prev_lowest_prices = price_list
                except (json.JSONDecodeError, ZeroDivisionError, TypeError, ValueError, AttributeError) as e:
                    logger.warning(f"处理商品 {goods_id} 的价格列表时出错: {str(e)}")
                    continue
            
            # 计算价格变化的比例（相对于最大变化幅度）
            avg_price_change = sum(price_changes) / len(price_changes) if price_changes else 0
            price_change_ratio = avg_price_change / max_price_change if max_price_change > 0 else 0
            avg_daily_changes = len(price_change_days) / date_span  # 使用实际天数计算
            
            # 根据比例评分（3分）
            if price_change_ratio >= 0.8:    # 平均变化达到最大变化的80%以上
                price_score = 3
            elif price_change_ratio >= 0.5:  # 达到50%以上
                price_score = 2
            elif price_change_ratio > 0:     # 有价格变化
                price_score = 1
            else:
                price_score = 0
            
            logger.info(f"价格波动得分：数据跨度{date_span}天，发生变化{len(price_change_days)}天，日均{avg_daily_changes:.1f}次，"
                       f"最大变化幅度{max_price_change:.2%}，平均变化幅度{avg_price_change:.2%}，"
                       f"变化比例{price_change_ratio:.2%}，得分{price_score}分")
            
            # 最终得分
            total_score = activity_score + sales_score + price_score
            logger.info(f"商品 {goods_id} 活跃度评分明细 - 活动频率: {activity_score}, 在售数量变化: {sales_score}, 价格波动: {price_score}")
            return (total_score, activity_score, sales_score, price_score)
            
        except Exception as e:
            logger.error(f"计算商品 {goods_id} 的交易频率得分时出错: {str(e)}")
            return (0, 0, 0, 0)

    def calculate_price_trend_score(self, history_prices: List[float], timestamps: List[float]) -> Tuple[float, float, float, float]:
        """
        计算价格趋势得分（10分）
        评分维度：
        1. 趋势方向和强度（5分）：
           - 稳定（变化<1%）：4分
           - 上涨：4-5分
           - 下跌：2-4分
        2. 价格变化幅度（2.5分）：
           - 波动<5%：1.5分
           - 波动5%-15%：2.5分
           - 波动>15%：递减扣分
        3. 趋势稳定性（2.5分）：
           - R方>0.7：2.5分
           - R方>0.5：2分
           - R方>0.3：1.5分
           - R方<=0.3：1分
        """
        if len(history_prices) < 2:
            return (0, 0, 0, 0)
            
        try:
            # 对时间戳进行分组处理
            time_price_dict = {}
            for t, p in zip(timestamps, history_prices):
                if t not in time_price_dict:
                    time_price_dict[t] = []
                time_price_dict[t].append(p)
            
            # 对每个时间点取平均价格
            unique_timestamps = sorted(time_price_dict.keys())
            if len(unique_timestamps) < 2:
                logger.warning("不同时间点少于2个，无法进行趋势分析")
                return (0, 0, 0, 0)
                
            unique_prices = [np.mean(time_price_dict[t]) for t in unique_timestamps]
            
            # 1. 计算趋势方向和强度（5分）
            slope, intercept, r_value, p_value, std_err = stats.linregress(unique_timestamps, unique_prices)
            r_squared = r_value ** 2
            
            # 计算平均价格和价格变化百分比
            mean_price = np.mean(unique_prices)
            total_time = unique_timestamps[-1] - unique_timestamps[0]
            if total_time == 0:  # 防止除零错误
                logger.warning("时间跨度为0，无法计算价格变化趋势")
                return (0, 0, 0, 0)
                
            price_change_percent = (slope * total_time) / mean_price * 100
            
            # 根据价格变化趋势评分
            trend_score = 0
            if abs(price_change_percent) < 1:  # 价格变化小于1%
                trend_score = 4  # 稳定
                logger.info(f"价格趋势稳定，变化率{price_change_percent:.2f}%，得分{trend_score}")
            elif price_change_percent > 1:  # 上涨
                trend_score = min(4 + price_change_percent, 5)  # 最高5分
                logger.info(f"价格呈上涨趋势，变化率{price_change_percent:.2f}%，得分{trend_score}")
            else:  # 下跌
                trend_score = max(2, 4 + price_change_percent)  # 最低2分
                logger.info(f"价格呈下跌趋势，变化率{price_change_percent:.2f}%，得分{trend_score}")
                
            # 2. 计算价格变化幅度得分（2.5分）
            price_range = (max(unique_prices) - min(unique_prices)) / min(unique_prices)
            if price_range < 0.05:
                range_score = 1.5
            elif price_range < 0.15:
                range_score = 2.5
            else:
                range_score = max(0, 2.5 - (price_range - 0.15) * 5)

            # 3. 计算趋势稳定性得分（2.5分）
            if r_squared > 0.7:
                stability_score = 2.5
            elif r_squared > 0.5:
                stability_score = 2
            elif r_squared > 0.3:
                stability_score = 1.5
            else:
                stability_score = 1

            # 计算总分
            total_score = trend_score + range_score + stability_score
            return (total_score, trend_score, range_score, stability_score)
            
        except Exception as e:
            logger.error(f"计算价格趋势得分时出错: {str(e)}", exc_info=True)
            return (0, 0, 0, 0)

    def calculate_time_activity_score(self, hourly_trades: Dict[int, int]) -> float:
        """
        计算当前时段活跃度得分（10分）
        """
        if not hourly_trades:
            return 0
            
        # 获取当前小时
        current_hour = datetime.now().hour
        
        # 计算总交易量
        total_trades = sum(hourly_trades.values())
        if total_trades == 0:
            return 0
            
        # 计算当前时段占比
        current_hour_trades = hourly_trades.get(current_hour, 0)
        hour_percentage = (current_hour_trades * 100.0) / total_trades
        
        # 评分规则
        if hour_percentage > 20:
            return 10
        elif hour_percentage > 15:
            return 8
        elif hour_percentage > 10:
            return 6
        elif hour_percentage > 5:
            return 4
        return 2

    def calculate_historical_success_score(self, success_count: int, total_count: int) -> float:
        """
        计算历史成功率得分（10分）
        """
        if total_count == 0:
            return 0
            
        success_rate = (success_count * 100.0) / total_count
        
        if success_rate > 80:
            return 10
        elif success_rate > 60:
            return 8
        elif success_rate > 40:
            return 6
        elif success_rate > 20:
            return 4
        return 2

    def determine_grade(self, total_score: float) -> str:
        """
        根据总分确定等级
        """
        if total_score >= 90:
            return 'S'
        elif total_score >= 80:
            return 'A'
        elif total_score >= 70:
            return 'B'
        return 'C'

    def analyze_goods(self, goods_id: int) -> Optional[ScoreResult]:
        """
        分析商品并计算总分
        权重分配：
        - 利润空间（40分）：反映商品的盈利能力
        - 交易频率（40分）：反映商品的活跃程度
        - 价格稳定性（10分）：反映价格的波动情况
        - 价格趋势（10分）：反映价格的变化方向
        总分：100分
        """
        try:
            # 初始化结果对象
            result = ScoreResult(goods_id=goods_id)
            
            # 获取最近7天的扫描记录
            seven_days_ago = datetime.now() - timedelta(days=7)
            records = self.scan_record_manager.get_records_by_goods_id(
                goods_id=str(goods_id),  # 需要转换为字符串
                start_time=seven_days_ago
            )
            
            if not records:
                logger.warning(f"商品 {goods_id} 没有最近7天的扫描记录")
                return None
                
            # 从扫描记录中提取价格列表和时间
            prices = []
            timestamps = []
            hourly_trades = {}  # 记录每小时的交易次数
            
            for record in records:
                if record['price_list']:  # 注意这里使用字典访问
                    # price_list是JSON格式的价格列表
                    price_data = record['price_list']
                    try:
                        if isinstance(price_data, str):
                            price_list = json.loads(price_data)
                        else:
                            price_list = price_data
                            
                        # 确保价格列表中的值都是数字
                        price_list = [float(p) for p in price_list if p is not None]
                        if price_list:
                            prices.append(price_list[0])  # 使用最低价
                            timestamps.append(record['create_at'].timestamp())
                            
                            # 记录交易时段
                            hour = record['create_at'].hour
                            hourly_trades[hour] = hourly_trades.get(hour, 0) + 1
                            
                    except (json.JSONDecodeError, ValueError, TypeError, IndexError) as e:
                        logger.warning(f"解析商品 {goods_id} 的价格列表时出错: {str(e)}")
                        continue
            
            if not prices:
                logger.warning(f"商品 {goods_id} 没有有效的价格数据")
                return None
                
            # 1. 计算价格稳定性得分（10分）
            stability_scores = self.calculate_price_stability_score(goods_id, prices)
            result.price_stability_score = stability_scores[0]
            result.stability_cv_score = stability_scores[1]
            result.stability_volatility_score = stability_scores[2]
            
            # 2. 计算利润空间得分（40分）
            profit_scores = self.calculate_profit_potential_score(goods_id)
            result.profit_potential_score = profit_scores[0]
            result.profit_rate_score = profit_scores[1]
            result.profit_frequency_score = profit_scores[2]
            result.profit_time_weighted_score = profit_scores[3]
            
            # 3. 计算交易频率得分（40分）
            frequency_scores = self.calculate_trading_frequency_score(goods_id)
            result.trading_frequency_score = frequency_scores[0]
            result.frequency_activity_score = frequency_scores[1]
            result.frequency_selling_change_score = frequency_scores[2]
            result.frequency_price_fluctuation_score = frequency_scores[3]
            
            # 4. 计算价格趋势得分（10分）
            trend_scores = self.calculate_price_trend_score(prices, timestamps)
            result.price_trend_score = trend_scores[0]
            result.trend_direction_score = trend_scores[1]
            result.trend_range_score = trend_scores[2]
            result.trend_stability_score = trend_scores[3]
            
            # 5. 计算时间活跃度得分（10分）
            result.time_activity_score = self.calculate_time_activity_score(hourly_trades)
            
            # 6. 计算历史成功率得分（10分）
            # 这里使用一个简单的示例，你需要根据实际情况修改
            success_count = len([r for r in records if r.get('success')])
            result.historical_success_score = self.calculate_historical_success_score(success_count, len(records))
            
            # 计算总分和等级
            result.total_score = (
                result.price_stability_score +
                result.profit_potential_score +
                result.trading_frequency_score +
                result.price_trend_score
            )
            result.grade = self.determine_grade(result.total_score)
            
            # 设置附加信息
            result.last_7d_trade_count = len(records)
            result.last_7d_avg_price = sum(prices) / len(prices)
            result.price_variance = np.std(prices) if len(prices) > 1 else 0
            result.success_rate = (success_count * 100.0) / len(records) if records else 0
            
            return result
            
        except Exception as e:
            logger.error(f"分析商品 {goods_id} 时出错: {str(e)}", exc_info=True)
            return None

    def batch_analyze_goods(self, goods_ids: List[int]) -> List[ScoreResult]:
        """
        批量分析商品
        """
        results = []
        for goods_id in goods_ids:
            result = self.analyze_goods(goods_id)
            if result:
                results.append(result)
        return results

    def analyze_all(self):
        """
        分析所有商品
        """
        try:
            # 获取所有在扫描记录中的商品ID
            sql = """
            SELECT DISTINCT goods_id 
            FROM scan_records 
            WHERE scan_start_time >= datetime('now', '-7 days')
            """
            goods_ids = self.score_manager.db.execute(sql)
            if not goods_ids:
                logger.error("没有找到最近7天的扫描记录")
                return
                
            goods_ids = [item[0] for item in goods_ids]
            logger.info(f"找到 {len(goods_ids)} 个商品待分析")
            
            # 批量分析商品
            results = self.batch_analyze_goods(goods_ids)
            if not results:
                logger.error("商品分析失败")
                return
                
            logger.info(f"成功分析 {len(results)} 个商品")
            
            # 保存分析结果
            if self.score_manager.batch_save_score_results(results):
                logger.info("评分结果已保存到数据库")
        
        except Exception as e:
            logger.error(f"分析过程中出错: {str(e)}", exc_info=True)

def main():
    """
    测试商品评分系统
    """
    import sys
    import os
    
    try:
        # 初始化分析器和管理器
        analyzer = GoodsScoreAnalyzer()
        manager = GoodsScoreManager()
        
        # 启动定时分析
        analyzer.start()
        
        # 等待5分钟后停止分析
        time.sleep(300)
        analyzer.stop()
        
    except Exception as e:
        logger.error(f"分析过程中出错: {str(e)}", exc_info=True)

if __name__ == "__main__":
    main()
